package com.info.zhiduoduo.common.utils.poi;

import com.info.zhiduoduo.common.utils.LogUtil;

import com.itextpdf.text.Document;
import com.itextpdf.text.Image;
import com.itextpdf.text.Rectangle;
import com.itextpdf.text.pdf.PdfWriter;
import org.apache.poi.ooxml.POIXMLDocument;
import org.apache.poi.xwpf.usermodel.PositionInParagraph;
import org.apache.poi.xwpf.usermodel.TextSegment;
import org.apache.poi.xwpf.usermodel.UnderlinePatterns;
import org.apache.poi.xwpf.usermodel.VerticalAlign;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
import org.apache.poi.xwpf.usermodel.XWPFRun;
import org.apache.poi.xwpf.usermodel.XWPFTable;
import org.apache.poi.xwpf.usermodel.XWPFTableCell;
import org.apache.poi.xwpf.usermodel.XWPFTableRow;
import org.apache.xmlbeans.XmlCursor;
import org.apache.xmlbeans.XmlObject;
import org.docx4j.Docx4J;
import org.docx4j.convert.out.FOSettings;
import org.docx4j.fonts.IdentityPlusMapper;
import org.docx4j.fonts.Mapper;
import org.docx4j.fonts.PhysicalFonts;
import org.docx4j.jaxb.Context;
import org.docx4j.openpackaging.packages.WordprocessingMLPackage;
import org.docx4j.wml.RFonts;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTBr;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTbl;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.STMerge;

import java.io.*;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import fr.opensagres.poi.xwpf.converter.pdf.PdfConverter;
import fr.opensagres.poi.xwpf.converter.pdf.PdfOptions;

public class DocUtils {

	/**
	 将doc输出 , 再转入inputstream

	 @param doc
	 @return
	 @throws Exception
	 @author Administrator
	 2015年7月6日
	 */
	public static InputStream exportToIs(XWPFDocument doc) throws Exception {
		ByteArrayOutputStream baos = new ByteArrayOutputStream();
		doc.write(baos);
		baos.flush();

		byte[] aa = baos.toByteArray();
		InputStream in = new ByteArrayInputStream(aa, 0, aa.length);
		baos.close();

		return in;
	}

	/**
	 将doc转入输出流

	 @param doc
	 @param out
	 @throws Exception
	 @author Administrator
	 2015年7月6日
	 */
	public static void write(XWPFDocument doc, OutputStream out) throws Exception {
		doc.write(out);
		out.flush();
		out.close();
	}

	/**
	 将doc输出到file

	 @param doc
	 @param file
	 @throws Exception
	 @author Administrator
	 2015年7月6日
	 */
	public static void write(XWPFDocument doc, File file) throws Exception {
		FileOutputStream fos = new FileOutputStream(file);
		doc.write(fos);
		fos.close();
	}

	/**
	 将doc输出到指定的文件上

	 @param doc
	 @param fileName
	 @throws Exception
	 @author Administrator
	 2015年7月6日
	 */
	public static void write(XWPFDocument doc, String fileName) throws Exception {
		FileOutputStream fos = new FileOutputStream(new File(fileName));
		doc.write(fos);
		fos.close();
		doc.close();
	}

	/**
	 从指定的文件上获取doc文档

	 @param fileName
	 @return
	 @throws Exception
	 @author Administrator
	 2015年7月6日
	 */
	public static XWPFDocument open(String fileName) throws Exception {
		return new XWPFDocument(POIXMLDocument.openPackage(fileName));
	}

	/**
	 从指定的文件上获取doc文档

	 @param file
	 @return
	 @throws Exception
	 @author Administrator
	 2015年7月6日
	 */
	public static XWPFDocument open(File file) throws Exception {
		return new XWPFDocument(new FileInputStream(file));
	}

	/**
	 从输入流上获取doc文档

	 @param in
	 @return
	 @throws Exception
	 @author Administrator
	 2015年7月6日
	 */
	public static XWPFDocument open(InputStream in) throws Exception {
		return new XWPFDocument(in);
	}

	/**
	 替换doc中所有的段落值

	 @param doc
	 @param paramData
	 */
	public static void replaceInPara(XWPFDocument doc, Map<String, Object> paramData) {
		Iterator<XWPFParagraph> iterator = doc.getParagraphsIterator();
		XWPFParagraph para;
		while (iterator.hasNext()) {
			para = iterator.next();
			replaceInPara(para, paramData);
		}
	}

	/**
	 处理要替换的文字在多个run中的情况.

	 @param para
	 @param paramData
	 */
	// 替换文本 已处理跨行的情况
	// 注意 文档中 不能出现类似$${\w+}的字符，由于searchText会一个字符一个字符做比价，找到第一个比配的开始计数
	public static void ReplaceInParagraph(XWPFParagraph para, Map<String, Object> paramData) {

		List<XWPFRun> runs = para.getRuns();
		Set<Map.Entry<String, Object>> entries = paramData.entrySet();
		Iterator<Map.Entry<String, Object>> iterator = entries.iterator();
		while (iterator.hasNext()) {
			Map.Entry<String, Object> entry = iterator.next();
			String find = entry.getKey();
			String replValue = entry.getValue().toString();
			TextSegment found = para.searchText("${" + find + "}", new PositionInParagraph());
			if (found != null) {
				// 判断查找内容是否在同一个Run标签中
				if (found.getBeginRun() == found.getEndRun()) {
					XWPFRun run = runs.get(found.getBeginRun());
					String runText = run.getText(run.getTextPosition());
					Matcher matcher = matcher(runText);
					String replaced = matcher.replaceFirst(replValue);
					//					String replaced = runText.replace(find, replValue);
					run.setText(replaced, 0);

				} else {
					// 存在多个Run标签
					StringBuilder sb = new StringBuilder();
					for (int runPos = found.getBeginRun(); runPos <= found.getEndRun(); runPos++) {
						XWPFRun run = runs.get(runPos);
						sb.append(run.getText((run.getTextPosition())));
					}
					String connectedRuns = sb.toString();
					Matcher matcher = matcher(connectedRuns);
					String replaced = matcher.replaceFirst(replValue);
					//					String replaced = connectedRuns.replace("${" + find + "}", replValue);
					XWPFRun firstRun = runs.get(found.getBeginRun());
					firstRun.setText(replaced, 0);
					// 删除后边的run标签
					for (int runPos = found.getBeginRun() + 1; runPos <= found.getEndRun(); runPos++) {
						// 清空其他标签内容
						XWPFRun partNext = runs.get(runPos);
						partNext.setText("", 0);
					}
				}
			}
		}
		// 完成第一遍查找,检测段落中的标签是否已经替换完 TODO 2016-06-14忘记当时处于什么考虑 加入这段代码
		// Pattern pattern = Pattern.compile(regex);
		// Matcher matcher = pattern.matcher(para.getText());
		// boolean find = matcher.find();
		// if (find) {
		// ReplaceInParagraph(tagList, para, regex);
		// find = false;
		// }
	}

	/**
	 替换段落中的值

	 @param para
	 @param paramData
	 */
	public static void replaceInPara(XWPFParagraph para, Map<String, Object> paramData) {
		List<XWPFRun> runs;
		Matcher matcher;
		Map<String, Object> mapAttr = new HashMap<String, Object>();
		LogUtil.info("段落文字: " + para.getParagraphText());
		if (matcher(para.getParagraphText()).find()) {
			LogUtil.info("找到可以替换的地方");
			runs = para.getRuns();
			LogUtil.info("段落中runs 数量 = " + runs.size());
			for (int i = 0; i < runs.size(); i++) {
				XWPFRun run = runs.get(i);
				String runText = run.toString();
				LogUtil.info("runText = " + runText);
				matcher = matcher(runText);
				if (matcher.find()) {
					LogUtil.info("在run中找到可以替换的.");
					matcher.reset();
					while ((matcher = matcher(runText)).find()) {
						mapAttr = getWordXWPFRunStyle(run);
						runText = matcher.replaceFirst(String.valueOf(paramData.get(matcher.group(1))));
					}
					// 直接调用XWPFRun的setText()方法设置文本时，在底层会重新创建一个XWPFRun，把文本附加在当前文本后面，
					// 所以我们不能直接设值，需要先删除当前run,然后再自己手动插入一个新的run。

					try {
						//有时会莫名其妙删除报错, 报i 指针越界.
						para.removeRun(i);
					} catch (Exception e) {
						e.printStackTrace();
					}
					XWPFRun runNew = para.insertNewRun(i);
					setWordXWPFRunStyle(runNew, mapAttr, runText);
					LogUtil.info("被替换的文字 :" + runText);
				}

			}
		}
		LogUtil.info("替换后para = " + para.getParagraphText());
	}

	/**
	 获取该段文字的格式

	 @param runOld
	 @return
	 */
	private static Map<String, Object> getWordXWPFRunStyle(XWPFRun runOld) {
		Map<String, Object> mapAttr = new HashMap<String, Object>();
		mapAttr.put("Color", runOld.getColor());
		if (-1 == runOld.getFontSize()) {
			mapAttr.put("FontSize", 12);
		} else {
			mapAttr.put("FontSize", runOld.getFontSize());
		}
		mapAttr.put("Subscript", runOld.getSubscript());
		mapAttr.put("Underline", runOld.getUnderline());
		mapAttr.put("FontFamily", runOld.getFontFamily());
		mapAttr.put("Bold", runOld.isBold());
		mapAttr.put("Italic", runOld.isItalic());
		return mapAttr;
	}

	/**
	 设置该段文字的格式

	 @param runNew
	 @param mapAttr
	 @param text
	 @return
	 */
	private static XWPFRun setWordXWPFRunStyle(XWPFRun runNew, Map<String, Object> mapAttr, String text) {
		runNew.setColor((String) mapAttr.get("Color"));
		if ("-1".equals(mapAttr.get("FontSize").toString())) {
			// 五号字只能处理为10磅,无法设置为10.5磅
			runNew.setFontSize(12);
		} else {
			runNew.setFontSize((Integer) mapAttr.get("FontSize"));
		}
		runNew.setBold((boolean) mapAttr.get("Bold"));
		runNew.setItalic((boolean) mapAttr.get("Italic"));
		runNew.setUnderline((UnderlinePatterns) mapAttr.get("Underline"));
		runNew.setText(text);
		runNew.setSubscript((VerticalAlign) mapAttr.get("Subscript"));
		runNew.setFontFamily((String) mapAttr.get("FontFamily"));
		return runNew;
	}

	/**
	 匹配doc中的占位符 ${}

	 @param str
	 @return
	 */
	private static Matcher matcher(String str) {
		Pattern pattern = Pattern.compile("\\$\\{(.+?)\\}", Pattern.CASE_INSENSITIVE);
		Matcher matcher = pattern.matcher(str);
		return matcher;
	}

	/**
	 @param doc
	 @param listData
	 @param paraData
	 */
	public static void replaceInTable(XWPFDocument doc, List<String[]> listData, Map paraData) {
		Iterator<XWPFTable> iterator = doc.getTablesIterator();
		XWPFTable table;
		List<XWPFTableRow> rows;
		List<XWPFTableCell> cells;
		List<XWPFParagraph> paras;
		while (iterator.hasNext()) {
			table = iterator.next();
			rows = table.getRows();
			if (matcher(table.getText()).find()) {
				// 模板固定表格赋值(根据${}匹配赋值)
				for (XWPFTableRow row : rows) {
					cells = row.getTableCells();
					for (XWPFTableCell cell : cells) {
						paras = cell.getParagraphs();
						for (XWPFParagraph para : paras) {
							replaceInPara(para, paraData);
						}
					}
				}
			} else {
				// 模板LIST表格赋值(需手动增加行)
				replaceInTbl(table, listData, null);
			}
		}
	}

	/**
	 替换表格中的值

	 @param table     表格
	 @param tableList 表格循环列表值
	 @param totalMap  表格总计栏的值
	 */
	public static void replaceInTbl(XWPFTable table, List<String[]> tableList, Map<String, Object> totalMap) {
		//1.先替换总计栏模板变量字段：
		if (totalMap != null && !totalMap.isEmpty()) {
			XWPFTableRow totalRow = table.getRow(table.getNumberOfRows() - 1);
			List<XWPFTableCell> tableCells = totalRow.getTableCells();
			tableCells.stream().flatMap(cell -> cell.getParagraphs().stream()).forEach(para -> DocUtils.ReplaceInParagraph(para,
					totalMap));
		}

		//2.创建行,根据需要插入的数据添加新行,不处理表头
		for (int i = 1; i < tableList.size(); i++) {
			XWPFTableRow targetRow = table.insertNewTableRow(i + 1);
			targetRow.getCtRow().setTrPr(table.getRow(i).getCtRow().getTrPr());
			List<XWPFTableCell> cellList = table.getRow(i).getTableCells();
			XWPFTableCell targetCell = null;
			for (XWPFTableCell sourceCell : cellList) {
				targetCell = targetRow.addNewTableCell();
				targetCell.getCTTc().setTcPr(sourceCell.getCTTc().getTcPr());
				targetCell.getParagraphs().get(0).getCTP().setPPr(sourceCell.getParagraphs().get(0).getCTP().getPPr());
				//复制单元格格式
				copyTableCell(targetCell, sourceCell);
			}

		}
		//3.遍历表格插入数据
		List<XWPFTableRow> rows = table.getRows();
		for (int i = 1; i < rows.size() && i <= tableList.size(); i++) {
			XWPFTableRow newRow = table.getRow(i);
			List<XWPFTableCell> cells = newRow.getTableCells();
			for (int j = 0; j < cells.size(); j++) {
				XWPFTableCell cell = cells.get(j);
				XWPFParagraph paragraph = cell.getParagraphs().get(0);
				XWPFRun cellR = null;
				if (paragraph.getRuns() != null && !paragraph.getRuns().isEmpty()) {
					cellR = paragraph.getRuns().get(0);
				} else {
					cellR = paragraph.createRun();
				}
				cellR.setText(tableList.get(i - 1)[j], 0);
				//清空后面多余的run的内容
				for (int runPos = 1; runPos < paragraph.getRuns().size(); runPos++) {
					XWPFRun partNext = paragraph.getRuns().get(runPos);
					partNext.setText("", 0);
				}
			}
		}
		//如果合计行需要合并单元格的话
		//		mergeCellsHorizontal(table, tableList.size(), 0, 2);
	}

	public static void mergeCellsHorizontal(XWPFTable table, int row, int fromCell, int toCell) {
		for (int cellIndex = fromCell; cellIndex <= toCell; cellIndex++) {
			XWPFTableCell cell = table.getRow(row).getCell(cellIndex);
			if (cellIndex == fromCell) {
				// The first merged cell is set with RESTART merge value
				cell.getCTTc().addNewTcPr().addNewHMerge().setVal(STMerge.RESTART);
			} else {
				// Cells which join (merge) the first one, are set with CONTINUE
				cell.getCTTc().addNewTcPr().addNewHMerge().setVal(STMerge.CONTINUE);
			}
		}
	}

	/**
	 从模板表格复制到新表格,只复制表头,一行模板行,和合计行

	 @param newTable
	 @param sourceTable
	 @return
	 */
	public static XWPFTable copyTemplateTable(XWPFTable newTable, XWPFTable sourceTable) {
		if (sourceTable == null) {
			return null;
		}

		List<XWPFTableRow> rows = sourceTable.getRows();
		if (rows == null || rows.isEmpty()) {
			return null;
		}
		for (int i = 0; i < newTable.getRows().size(); i++) {
			newTable.removeRow(i);
		}

		int size = rows.size();
		int rowIndex = 0;
		for (int i = 0; i < size; i++) {
			if (size > 3 && i > 1 && i < size - 1) {
				//只复制表头 一行模板行 和 合计行.
				continue;
			}
			XWPFTableRow sourceRow = sourceTable.getRow(i);
			//1.插入新行, 默认新行是没有cell的
			XWPFTableRow targetRow = newTable.insertNewTableRow(rowIndex);
			rowIndex++;
			//此方法插入新行,且cell按照上面一行进行自动创建
			//			XWPFTableRow targetRow = newTable.createRow();
			//2.遍历,创建cell,并复制模板格式
			targetRow.getCtRow().setTrPr(sourceRow.getCtRow().getTrPr());
			List<XWPFTableCell> cellList = sourceRow.getTableCells();
			XWPFTableCell sourceCell = null;
			XWPFTableCell targetCell = null;
			for (int j = 0; j < cellList.size(); j++) {
				sourceCell = sourceRow.getCell(j);
				targetCell = targetRow.createCell();

				targetCell.getCTTc().setTcPr(sourceCell.getCTTc().getTcPr());
				XWPFParagraph sourceParagraph = null;
				XWPFParagraph targetParagraph = null;
				List<XWPFParagraph> paragraphs = sourceCell.getParagraphs();
				if (paragraphs != null) {
					for (int k = 0; k < paragraphs.size(); k++) {
						targetCell.removeParagraph(0);
						sourceParagraph = paragraphs.get(k);
						targetParagraph = targetCell.addParagraph();
						targetParagraph.getCTP().setPPr(sourceParagraph.getCTP().getPPr());
						for (XWPFRun sourcerun : sourceParagraph.getRuns()) {
							XWPFRun targetrun = targetParagraph.createRun();
							copyRun(targetrun, sourcerun);
						}
					}
				}
			}
		}
		return newTable;
	}

	private static void copyRun(XWPFRun target, XWPFRun source) {
		target.getCTR().setRPr(source.getCTR().getRPr());
		// 获取原来run的格式,并复制格式及设置文本
		Map<String, Object> runStyle = getWordXWPFRunStyle(source);
		setWordXWPFRunStyle(target, runStyle, source.text());
	}

	public static void copyParagraph(XWPFParagraph target, XWPFParagraph source) {
		// 设置段落样式
		target.getCTP().setPPr(source.getCTP().getPPr());
		// 添加Run标签
		for (int pos = 0; pos < target.getRuns().size(); pos++) {
			target.removeRun(pos);
		}
		for (XWPFRun s : source.getRuns()) {
			XWPFRun targetrun = target.createRun();
			copyRun(targetrun, s);
		}
	}

	private static void copyTableCell(XWPFTableCell target, XWPFTableCell source) {
		// 列属性
		target.getCTTc().setTcPr(source.getCTTc().getTcPr());
		// 删除目标 targetCell 所有单元格
		for (int pos = 0; pos < target.getParagraphs().size(); pos++) {
			target.removeParagraph(pos);
		}
		// 添加段落
		for (XWPFParagraph sp : source.getParagraphs()) {
			XWPFParagraph targetP = target.addParagraph();
			copyParagraph(targetP, sp);
		}
	}

	private static void copytTableRow(XWPFTableRow target, XWPFTableRow source) {
		// 复制样式
		target.getCtRow().setTrPr(source.getCtRow().getTrPr());
		// 复制单元格
		for (int i = 0; i < target.getTableCells().size(); i++) {
			copyTableCell(target.getCell(i), source.getCell(i));
		}
	}

	public static XWPFTable copyTable2(XWPFTable source) {
		if (source == null) {
			return null;
		}
		CTTbl newCTTbl = CTTbl.Factory.newInstance();
		CTTbl ctTbl = source.getCTTbl();
		newCTTbl.set(ctTbl);
		XWPFTable newTable = new XWPFTable(newCTTbl, source.getBody());
		for (int i = 0; i < source.getRows().size(); i++) {
			XWPFTableRow row = newTable.getRow(i);
			copytTableRow(row, source.getRow(i));
		}
		return newTable;
	}

	/**
	 判断该段落是否是分页符

	 @param paragraph
	 @return
	 */
	public static boolean isPageBreak(XWPFParagraph paragraph) {
		List<XWPFRun> runs = paragraph.getRuns();
		Iterator<XWPFRun> iterator = runs.iterator();
		boolean isPageBreak = false;
		while (iterator.hasNext()) {
			XWPFRun run = iterator.next();
			XmlCursor c = run.getCTR().newCursor();
			c.selectPath("./*");
			while (c.toNextSelection()) {
				XmlObject o = c.getObject();
				if (o instanceof CTBr) {
					isPageBreak = true;
					break;
				}
			}
		}
		return isPageBreak;
	}

	/**
	 根据图片文件名, 获取doc中的图片类型

	 @param imgFile
	 @return
	 */
	public static int getPictureType(String imgFile) {
		int format;

		if (imgFile.endsWith(".emf")) format = XWPFDocument.PICTURE_TYPE_EMF;
		else if (imgFile.endsWith(".wmf")) format = XWPFDocument.PICTURE_TYPE_WMF;
		else if (imgFile.endsWith(".pict")) format = XWPFDocument.PICTURE_TYPE_PICT;
		else if (imgFile.endsWith(".jpeg") || imgFile.endsWith(".jpg")) format = XWPFDocument.PICTURE_TYPE_JPEG;
		else if (imgFile.endsWith(".png")) format = XWPFDocument.PICTURE_TYPE_PNG;
		else if (imgFile.endsWith(".dib")) format = XWPFDocument.PICTURE_TYPE_DIB;
		else if (imgFile.endsWith(".gif")) format = XWPFDocument.PICTURE_TYPE_GIF;
		else if (imgFile.endsWith(".tiff")) format = XWPFDocument.PICTURE_TYPE_TIFF;
		else if (imgFile.endsWith(".eps")) format = XWPFDocument.PICTURE_TYPE_EPS;
		else if (imgFile.endsWith(".bmp")) format = XWPFDocument.PICTURE_TYPE_BMP;
		else if (imgFile.endsWith(".wpg")) format = XWPFDocument.PICTURE_TYPE_WPG;
		else {
			System.err.println("Unsupported picture: " + imgFile + ". Expected emf|wmf|pict|jpeg|png|dib|gif|tiff|eps|bmp|wpg");
			format = 0;
		}
		return format;

	}

	public static void convertToPDF(XWPFDocument document, String outFile) throws Exception {

		//创建PDF选项
		PdfOptions pdfOptions = PdfOptions.create();//.fontEncoding("windows-1250")

		//执行PDF转化
		PdfConverter.getInstance().convert(document, new FileOutputStream(outFile), pdfOptions);

	}

	/**
	 docx文档转换为PDF

	 @param pdfPath PDF文档存储路径
	 @throws Exception 可能为Docx4JException, FileNotFoundException, IOException等
	 */
	public static void convertDocxToPDF(File docFile, String pdfPath) throws Exception {
		OutputStream os = null;
		try {
			WordprocessingMLPackage mlPackage = WordprocessingMLPackage.load(docFile);
			//Mapper fontMapper = new BestMatchingMapper();
			Mapper fontMapper = new IdentityPlusMapper();
			fontMapper.put("隶书", PhysicalFonts.get("LiSu"));
			fontMapper.put("宋体", PhysicalFonts.get("SimSun"));
			fontMapper.put("微软雅黑", PhysicalFonts.get("Microsoft Yahei"));
			fontMapper.put("黑体", PhysicalFonts.get("SimHei"));
			fontMapper.put("楷体", PhysicalFonts.get("KaiTi"));
			fontMapper.put("新宋体", PhysicalFonts.get("NSimSun"));
			fontMapper.put("华文行楷", PhysicalFonts.get("STXingkai"));
			fontMapper.put("华文仿宋", PhysicalFonts.get("STFangsong"));
			fontMapper.put("宋体扩展", PhysicalFonts.get("simsun-extB"));
			fontMapper.put("仿宋", PhysicalFonts.get("FangSong"));
			fontMapper.put("仿宋_GB2312", PhysicalFonts.get("FangSong_GB2312"));
			fontMapper.put("幼圆", PhysicalFonts.get("YouYuan"));
			fontMapper.put("华文宋体", PhysicalFonts.get("STSong"));
			fontMapper.put("华文中宋", PhysicalFonts.get("STZhongsong"));
			mlPackage.setFontMapper(fontMapper);

			String fontFamily = "SimSun";
			//			Resource fileRource = new ClassPathResource("/usr/local/reycookingtest/orderdoc/SIMHEI.TTF");
			//			String path =  fileRource.getFile().getAbsolutePath();

			// URL fontUrl = new URL("file:/usr/local/reycookingtest/orderdoc/SIMHEI.TTF");
			// PhysicalFonts.addPhysicalFont(fontUrl);
			//
			// PhysicalFont simheiFont = PhysicalFonts.get(fontFamily);
			// fontMapper.put(fontFamily, simheiFont);

			RFonts rfonts = Context.getWmlObjectFactory().createRFonts(); // 设置文件默认字体
			rfonts.setAsciiTheme(null);
			rfonts.setAscii(fontFamily);
			mlPackage.getMainDocumentPart().getPropertyResolver().getDocumentDefaultRPr().setRFonts(rfonts);

			os = new FileOutputStream(pdfPath);
			FOSettings foSettings = Docx4J.createFOSettings();
			foSettings.setWmlPackage(mlPackage);
			Docx4J.toFO(foSettings, os, Docx4J.FLAG_EXPORT_PREFER_XSL);

		} catch (Exception ex) {
			ex.printStackTrace();
		} finally {
			if (os != null) {
				os.close();
			}
		}
	}


    /**
     * 图片转pdf
     * @param source 图片路径
     * @param target  生成的pdfc存放路径
     */
	public static void imageConvertPdf(String source, String target) {
		Document document = new Document();
		//设置文档页边距
		document.setMargins(0,0,0,0);
		FileOutputStream fos = null;
		try {
			fos = new FileOutputStream(target);
			PdfWriter.getInstance(document,fos);
			//打开文档
			document.open();
			//获取图片的宽高
			Image image = Image.getInstance(source);
			float imageHeight=image.getScaledHeight();
			float imageWidth=image.getScaledWidth();
			//设置页面宽高与图片一致
			Rectangle rectangle = new Rectangle(imageWidth, imageHeight);
			document.setPageSize(rectangle);
			//图片居中
			image.setAlignment(Image.ALIGN_CENTER);
			//新建一页添加图片
			document.newPage();
			document.add(image);
		} catch (Exception ioe) {
			System.out.println(ioe.getMessage());
		} finally {
			//关闭文档
			document.close();
			try {
				fos.flush();
				fos.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
}
